package com.ok.common.ext

import com.kongzue.dialogx.dialogs.WaitDialog
import com.ok.common.base.AppContext
import com.ok.common.base.IBaseResponse
import com.ok.common.base.IViewModel
import com.ok.common.exception.HandleException
import com.ok.common.exception.ResponseException
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.transform

/**
 * Flow观察模式，统一拦截
 */
fun <T> Flow<IBaseResponse<T>>.observer(
    model: IViewModel? = null,
    loadingText: String = "加载中...",
    loading: Boolean = false,
    loadingDelay: Long = 0,
    tipError: Boolean = true,
    error: ((ResponseException) -> Unit?)? = null
): Flow<T?> =
    transform { value ->
        return@transform if (value.isSuccess()) {
            //处理成功
            emit(value.data())
        } else {
            throw ResponseException(value)
        }
    }.catch {
        //处理网络异常
        val exception = HandleException.handleException(it)
        if (tipError) {
            model?.apply {
                toast(exception.msg)
            } ?: run {
                AppContext.toast(exception.msg)
            }
        }
        if (error != null) {
            error(exception)
        }
    }.onStart {
        if (loading) {
            model?.apply {
                showLoading(loadingText)
            } ?: run {
                WaitDialog.show(loadingText)
            }
            if (loadingDelay > 0) delay(loadingDelay)
        }
    }.onCompletion {
        if (loading) {
            if (model != null) {
                model.dismissLoading()
            } else {
                WaitDialog.dismiss()
            }
        }
    }


fun <T> Flow<IBaseResponse<T>>.observe(
    loadingText: String = "加载中...",
    loading: Boolean = false,
    loadingDelay: Long = 0,
    start: () -> Unit,
    completion: () -> Unit,
    error: (ResponseException) -> Unit
): Flow<T?> =
    transform { value ->
        return@transform if (value.isSuccess()) {
            //处理成功
            emit(value.data())
        } else {
            throw ResponseException(value)
        }
    }.catch {
        //处理网络异常
        val exception = HandleException.handleException(it)
        AppContext.toast(exception.msg)
        error(exception)
    }.onStart {
        start()
    }.onCompletion {
        completion()
    }